#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <malloc.h>
#include <glib.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "lire_option.h"
#include "fonctions_client.h"



#define TBUFF 100

#define NI_MAXHOST 1023
#define NI_MAXSERV 32


#define TAILLE_BUFF 5000

typedef int SOCKET;

int main(int argc, char* argv[])
{
	Option *info;
	info = (Option *) malloc(sizeof(Option));
	lire_option(argc,argv,info);
	// structure pour faire la demande
	struct addrinfo hints;

	// structure pour stocker et lire les résultats
	struct addrinfo *result, *rp;

	/*Initialisation du socket*/
	SOCKET s = -1;
	
	// variables pour tester si les fonctions donnent un résultats ou une erreur
	int res;
	int bon;
	// Des variable pour contenir de adresse de machine et des numero de port afin de les afficher
	char hname[NI_MAXHOST], sname[NI_MAXSERV];

	// on remplit la structure hints de demande d'adresse
	memset(&hints, 0, sizeof(struct addrinfo));
	hints.ai_family = AF_INET;    /* IPv4 */
	hints.ai_socktype = SOCK_STREAM; /* socket flux connectée */
	hints.ai_flags = 0;  
	hints.ai_protocol = 0;          /* Any protocol */
	hints.ai_addrlen = 0; 
	hints.ai_addr = NULL;           
	hints.ai_canonname = NULL;
	hints.ai_next = NULL;
 
 	res = getaddrinfo(info->host, info->port, &hints, &result);
 
	if (res != 0)
	{
		// c'est une erreur
		fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
		exit(1);
  	}
  
	// si res = 0 le véritable résultat de la fontion est l'argument result
	// qui contient une liste d'addresse correspondant à la demande on va les
	// rester jusqu'a trouver une qui convient
	rp = result;
	bon = 0;

	while (rp != NULL)
	{
		// on parcourt la liste pour en trouver une qui convienne

		// on récupère des informations affichables
		res = getnameinfo(rp->ai_addr, rp->ai_addrlen,
		hname, NI_MAXHOST,
		sname, NI_MAXSERV,
		NI_NUMERICSERV|NI_NUMERICHOST);

		if (res != 0)
		{
			fprintf(stderr, "getnameinfo: %s\n", gai_strerror(res));
			exit (1);
		}

		// on essaye
		s = socket(rp->ai_family, rp->ai_socktype,rp->ai_protocol);
		// si le résultat est -1 cela n'a pas fonctionné on recommence avec la prochaine
		if (s == -1)
		{
			perror("Création de la socket");
			continue;
		}    

		// si la socket a été obtenue, on essaye de se connecter
		res = connect(s, rp->ai_addr, rp->ai_addrlen);
		recoitMessage(s);/*
		recoitDonnees(2,s);*/
		
		if (res == 0 )
		{
			// cela a fonctionné on est connecté
			bon = 1;
			break; 
		}
		else
		{
			// sinon le bind a été impossible, il faut fermer la socket
			perror("Impossible de se connecter");
			close (s);
		}

		rp = rp->ai_next;
	}

  	if (bon == 0)
	{
		// Cela n'a jamais fonctionné
		fprintf(stderr, "Aucune connexion possible\n");
		exit(1);
	}
	
	freeaddrinfo(result);           /* No longer needed */
	
	/*On se connecte avec le log et pass*/
	connexion(s,info->user,info->pass);	
	
	int taille=0;
	char *saisie;
	FILE * fd;
	
	if((info->nomfic)!=NULL){
		fd=fopen(info->nomfic,"r");
		if(fd==NULL){
			fprintf(stderr,"Le fichier de commandes n'existe pas...");
			return -5;
		}
		
	}
	
	
	while(1){
		
		/* Saisie de la commande*/
		if((info->nomfic)==NULL){
			getline(&saisie,&taille,stdin);
		}
		else{
			getline(&saisie,&taille,fd);
		}
		
		/*Execution de la commande*/
		if(strstr(saisie,"lister")){
			listerContenu(s,info->host,saisie);			
		}
		else{
			if(strstr(saisie,"recuperer")){
				recupereFichier(s,saisie,info->host);
			}
			else{
				if(strstr(saisie,"repertoire")){
					changeRepertoire(s,saisie,info->host);
				}
				else{
					if(strstr(saisie,"deconnecte\n")){
						envoieMessage(s,"QUIT\r\n");
						recoitMessage(s);
						close(s);
						return 0;
					}
					else{
						printf("Veuillez saisir une commande valide, merci. (RAPPEL : lister - recuperer <fichier> - repertoire <nomdurep> - deconnecte\n");
					}
				}

			}
		}
		memset(saisie,0,sizeof(saisie));
	}

	return 0;
}
